package com.inspur.edp.lcm.metadata.common;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.inspur.edp.lcm.metadata.api.IMdExtRuleContent;
import com.inspur.edp.lcm.metadata.api.IMetadataContent;
import com.inspur.edp.lcm.metadata.api.entity.GspMetadata;
import com.inspur.edp.lcm.metadata.api.entity.MetadataDto;
import com.inspur.edp.lcm.metadata.api.entity.MetadataHeader;
import com.inspur.edp.lcm.metadata.api.entity.MetadataReference;
import com.inspur.edp.lcm.metadata.common.configuration.MdExtRuleSerializerHelper;
import com.inspur.edp.lcm.metadata.common.configuration.MetadataSerializerHelper;
import com.inspur.edp.lcm.metadata.common.configuration.TransferSerializerHelper;
import com.inspur.edp.lcm.metadata.common.utils.TestUtils;
import com.inspur.edp.lcm.metadata.spi.MdExtendRuleSerializer;
import com.inspur.edp.lcm.metadata.spi.MetadataContentSerializer;
import com.inspur.edp.lcm.metadata.spi.MetadataTransferSerializer;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;

import java.util.Arrays;
import java.util.Collections;

import static org.junit.jupiter.api.Assertions.*;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.when;

@ExtendWith(MockitoExtension.class)
class MetadataDtoConverterTest {
    @Mock
    TransferSerializerHelper transferSerializerHelper;

    @Mock
    private MetadataSerializerHelper metadataSerializerHelper;

    @Mock
    private MetadataContentSerializer metadataContentSerializer;

    @Mock
    private IMetadataContent metadataContent;

    @Mock
    private MdExtRuleSerializerHelper mdExtRuleSerializerHelper;

    @Mock
    private MdExtendRuleSerializer mdExtendRuleSerializer;

    @Mock
    private IMdExtRuleContent mdExtRuleContent;

    private ObjectMapper mapper = MetadataSerializer.getMapper();

    @Test
    void asDto() throws JsonProcessingException {
        // 参数
        GspMetadata metadata = new GspMetadata(new MetadataHeader());
        metadata.getHeader().setType("type");
        MetadataReference metadataReference = new MetadataReference();
        metadataReference.setMetadata(new MetadataHeader("id1", "namespace1", "code1", "name1", "type1", "bizobjectID1"));
        metadataReference.setDependentMetadata(new MetadataHeader("id2", "namespace2", "code2", "name2", "type2", "bizobjectID2"));
        metadata.setRefs(Collections.singletonList(metadataReference));
        metadata.setContent(metadataContent);
        metadata.setExtendRule(mdExtRuleContent);
        // mock MetadataTransferSerializer
        TestUtils.setStaticFieldValue(TransferSerializerHelper.class, "singleton", transferSerializerHelper);
        when(transferSerializerHelper.getManager(any())).thenReturn(null);
        // mock content
        TestUtils.setStaticFieldValue(MetadataSerializerHelper.class, "singleton", metadataSerializerHelper);
        when(metadataSerializerHelper.getManager(any())).thenReturn(metadataContentSerializer);
        JsonNode jsonNode = mapper.readTree("{\"A\": \"a\"}");
        when(metadataContentSerializer.Serialize(any())).thenReturn(jsonNode);
        // mock extendRule
        TestUtils.setStaticFieldValue(MdExtRuleSerializerHelper.class, "singleton", mdExtRuleSerializerHelper);
        when(mdExtRuleSerializerHelper.getManager(any())).thenReturn(mdExtendRuleSerializer);
        JsonNode extRuleNode = mapper.readTree("{\"B\": \"b\"}");
        when(mdExtendRuleSerializer.serialize(any())).thenReturn(extRuleNode);
        // invoke
        MetadataDto dto = MetadataDtoConverter.asDto(metadata);
        assertTrue(dto.refs.contains("id2"));
        assertTrue(dto.getContent().contains("\"a\""));
        assertTrue(dto.getExtendRule().contains("\"b\""));
    }

    @Test
    void asMetadata() throws JsonProcessingException {
        // 参数
        MetadataDto metadataDto = new MetadataDto();
        metadataDto.setId("id");
        metadataDto.setCode("code");
        metadataDto.setName("name");
        metadataDto.setType("type");
        metadataDto.setExtented(false);
        metadataDto.setVersion("version");
        metadataDto.setBizobjectID("biziobjectID");
        metadataDto.setNameSpace("namespace");
        metadataDto.setExtendable(true);
        metadataDto.setLanguage("language");
        metadataDto.setFileName("filename");
        metadataDto.setIsTranslating(false);
        metadataDto.setPreviousVersion("previousVersion");
        metadataDto.setRelativePath("relativePath");
        MetadataReference metadataReference = new MetadataReference();
        metadataReference.setMetadata(new MetadataHeader("id1", "namespace1", "code1", "name1", "type1", "bizobjectID1"));
        metadataReference.setDependentMetadata(new MetadataHeader("id2", "namespace2", "code2", "name2", "type2", "bizobjectID2"));
        metadataDto.setRefs(mapper.writeValueAsString(Collections.singletonList(metadataReference)));
        // mock content
        metadataDto.setContent("{\"A\": \"a\"}");
        TestUtils.setStaticFieldValue(TransferSerializerHelper.class, "singleton", transferSerializerHelper);
        when(transferSerializerHelper.getManager(any())).thenReturn(null);
        TestUtils.setStaticFieldValue(MetadataSerializerHelper.class, "singleton", metadataSerializerHelper);
        when(metadataSerializerHelper.getManager(any())).thenReturn(metadataContentSerializer);
        when(metadataContentSerializer.DeSerialize(any())).thenReturn(metadataContent);
        // mock extendRule
        metadataDto.setExtendRule("{\"B\": \"b\"}");
        TestUtils.setStaticFieldValue(MdExtRuleSerializerHelper.class, "singleton", mdExtRuleSerializerHelper);
        when(mdExtRuleSerializerHelper.getManager(any())).thenReturn(mdExtendRuleSerializer);
        when(mdExtendRuleSerializer.deSerialize(any())).thenReturn(mdExtRuleContent);
        // invoke
        GspMetadata metadata = MetadataDtoConverter.asMetadata(metadataDto);
        assertEquals("id", metadata.getHeader().getId());
    }
}